using Engine.Graphics.VertexStructures;
using SharpDX;
using SharpDX.Direct3D11;

namespace Scenario_Editor.Tools
{
    internal class NodeMesh
    {
        #region Private Fields

        private Device device;
        private Buffer ib;
        private BufferDescription indexBufferDescription;
        private Vector3 position;
        private float size = 50.5f;
        private Buffer vb;
        private VertexBufferBinding vertexBufferBinding;
        private BufferDescription vertexBufferDescription;
        private CustomVertex.PositionColored[] vertices = new CustomVertex.PositionColored[2];

        /// <summary>
        /// The size above the ground
        /// </summary>
        private float yOffset = 1.0f;

        #endregion Private Fields

        #region Public Constructors

        public NodeMesh(Device device, Vector3 Position, System.Drawing.Color color)
        {
            this.device = device;
            vertices = new CustomVertex.PositionColored[4];
            Color4 color4 = new Color4(color.R / 255.0f, color.G / 255.0f, color.B / 255.0f, color.A / 255.0f);
            vertices[0].Color = color4;
            vertices[1].Color = color4;
            vertices[2].Color = color4;
            vertices[3].Color = color4;

            short[] indices = new short[] { 0, 1, 2, 3 };

            this.vertexBufferDescription = new BufferDescription()
            {
                BindFlags = BindFlags.VertexBuffer,
                CpuAccessFlags = 0,
                // OptionFlags = ResourceOptionFlags.BufferStructured,
                SizeInBytes = CustomVertex.PositionColored.SizeInBytes() * vertices.Length,
                Usage = ResourceUsage.Default
            };
            this.indexBufferDescription = new BufferDescription()
             {
                 BindFlags = BindFlags.IndexBuffer,
                 CpuAccessFlags = 0,
                 SizeInBytes = indices.Length * sizeof(short),
                 Usage = ResourceUsage.Default,
                 OptionFlags = ResourceOptionFlags.None
             };
            UpdatePosition(Position);
            ib = Buffer.Create(this.device, indices, this.indexBufferDescription);
        }

        #endregion Public Constructors

        #region Public Methods

        public void Dispose()
        {
            if (vb != null)
            {
                vb.Dispose();
            }
            if (ib != null)
            {
                ib.Dispose();
            }
        }

        public void Draw()
        {
            DeviceContext deviceContext = this.device.ImmediateContext;
            lock (deviceContext)
            {
                deviceContext.InputAssembler.SetVertexBuffers(0, this.vertexBufferBinding);
                deviceContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
                deviceContext.Draw(4, 0);
            }
        }

        public void UpdatePosition(Vector3 Position)
        {
            if (Position != this.position)
            {
                Position.Y += yOffset;
                Vector3 temp = new Vector3();
                temp.X = Position.X - size;
                temp.Y = Position.Y;
                temp.Z = Position.Z;
                vertices[0].Position = temp;

                temp.X = Position.X + size;
                temp.Y = Position.Y;
                temp.Z = Position.Z;
                vertices[1].Position = temp;

                temp.X = Position.X;
                temp.Y = Position.Y;
                temp.Z = Position.Z - size;
                vertices[2].Position = temp;

                temp.X = Position.X;
                temp.Y = Position.Y;
                temp.Z = Position.Z + size;
                vertices[3].Position = temp;

                vb = Buffer.Create(device, vertices, this.vertexBufferDescription);
                this.vertexBufferBinding = new VertexBufferBinding(this.vb, CustomVertex.PositionColored.SizeInBytes(), 0);

                this.position = Position;
            }
        }

        #endregion Public Methods
    }
}